home *** CD-ROM | disk | FTP | other *** search
/ Shareware Grab Bag / Shareware Grab Bag.iso / 090 / pr2fl1.arc / PR2FL.ASM next >
Encoding:
Assembly Source File  |  1985-10-29  |  10.5 KB  |  295 lines

  1. PAGE     ,132
  2. TITLE    PR2FL - PRINTER REDIRECTION
  3. SUBTTL   By Jim Kyle - May 28, 1985 - Version 1.0
  4. ;
  5. ;        This program redirects PRN output to a file. The filename is
  6. ;        supplied as a pathname when the program is invoked:
  7. ;
  8. ;                        PR2FL C:\FILES\PRTFIL.001
  9. ;
  10. ;        It achieves this goal by opening the file, saving the file's
  11. ;        DCB index (the content of its handle), and then faking an entry
  12. ;        in the handle table of its Program Segment Prefix to show that
  13. ;        the file is closed. Next, it extracts the content of the PRN
  14. ;        handle and saves it on the stack, stuffs the file's DCB index
  15. ;        into the PRN handle entry, and spawns a child copy of COMMAND.COM
  16. ;        to permit continued operation. While the child copy is running,
  17. ;        or any program called through the child copy is executing, all
  18. ;        output directed to the PRN device via standard DOS interfaces will
  19. ;        go instead to the redirection file.
  20. ;
  21. ;        To terminate redirection, the child copy of COMMAND.COM is
  22. ;        stopped via the EXIT command. Control then returns to PR2FL.COM,
  23. ;        which closes the redirection file, restores the original PRN index
  24. ;        value, displays a "Redirection Ended" message, and then returns
  25. ;        control to the copy of COMMAND.COM from which it was invoked.
  26. ;
  27. ;        This process inherently permits nesting. Each invocation of this
  28. ;        program takes away approximately 4K of RAM for the duration of
  29. ;        its execution (specifically, 3920 bytes). You can nest calls of
  30. ;        PR2FL as deeply as you have RAM available, and at each EXIT they
  31. ;        will automatically unwind themselves.
  32. ;
  33. ;        To assemble, use MASM, LINK, and EXE2BIN. If you find this
  34. ;        program useful, let me know. And if you find any bugs, by all
  35. ;        means tell me about them!
  36. ;                                        Jim Kyle
  37. ;                                        76703,762
  38. ;                                        SysOp, CLM SIG (GO CLM-332)
  39. ;
  40. ;       Modified GETPATH to correct for problems with numeric characters
  41. ;       Lew Paper
  42. ;       10/29/85
  43. PAGE
  44. ;
  45. CODE     SEGMENT PUBLIC 'CODE'
  46.         ASSUME   CS:CODE,DS:CODE,ES:CODE,SS:CODE
  47.  
  48.         ORG      0100H
  49.  
  50. START:   MOV     SP,OFFSET STACK         ;keep the stack safe
  51.         CALL     DOSVTST                 ;verify proper DOS version
  52.         CALL     GETPATH                 ;set up pointers to pathname
  53.         JNZ      HVPATH                  ;error check here if no path
  54.         MOV      DX,OFFSET NOPATH
  55.         JMP      SHORT FINI
  56. HVPATH:  CALL    REDIR                   ;get file and switch
  57.         PUSH     AX                      ;save for use at return
  58.         MOV      CMDLNP+2,CS             ;initialize parm block
  59.         MOV      FCB1P+2,CS
  60.         MOV      FCB2P+2,CS
  61.         MOV      SAVSP,SP                ;save stack pointer
  62.         CALL     GETCOM                  ;set up for COMSPEC (changes DS)
  63.         CALL     RELMEM                  ;release unneeded RAM
  64.         MOV      DX,SI                   ;DS:DX -> Pgm to run
  65.         MOV      BX,OFFSET PARMS         ;ES:BX -> Parm Block
  66.         MOV      AX,4B00H                ;AL=0  -> Execute program
  67.         INT      21H
  68.         MOV      AX,CS                   ;restore segments
  69.         MOV      SS,AX
  70.         MOV      ES,AX
  71.         MOV      DS,AX
  72.         MOV      SP,SAVSP                ;restore stack pointer
  73.         MOV      BX,4                    ;PRN handle (file)
  74.         MOV      AH,3EH                  ;close the file
  75.         INT      21H
  76.         POP      AX                      ;restore DCB indices
  77.         MOV      DI,1CH                  ;handle table offset for PRN in PSP
  78.         MOV      [DI],AH                 ;restore previous PRN
  79.         MOV      DX,OFFSET RTND          ;return message
  80. FINI:    PUSH    CS                      ;restore DS
  81.         POP      DS
  82.         MOV      AH,9                    ;send message
  83.         INT      21H
  84.         INT      20H                     ;then get out for keeps
  85. PAGE
  86. ;
  87. RELMEM:
  88. LAST     =       OFFSET STACK+17
  89.         MOV      AX,OFFSET LAST          ;release surplus memory
  90.         SHR      AX,1                    ;first convert to paragraphs
  91.         SHR      AX,1
  92.         SHR      AX,1
  93.         SHR      AX,1
  94.         MOV      BX,AX                   ;then stash in BX
  95.         MOV      AX,4A00H
  96.         INT      21H
  97.         RET
  98. ;
  99. SAVSP    DW      0
  100. ;
  101. RTND     DB      13,10,'Redirection Ended',13,10,36
  102. ;
  103. PARMS    DW      0                       ;env segment
  104. CMDLNP   DW      OFFSET CMDLIN,0         ;new command line
  105. FCB1P    DW      OFFSET FCB,0            ;new FCB1
  106. FCB2P    DW      OFFSET FCB,0            ;new FCB2
  107. ;
  108. CMDLIN   DB      CMDLEN                  ;length of command
  109. ;        DB      'COMMAND /D'            ;command line
  110. CMDLEN   EQU     $-CMDLIN-1
  111.         DB       13                      ;CR to terminate
  112. ;
  113. FCB      DB      0
  114.         DB       '           '
  115.         DW       0,0
  116. ;
  117.         DB       126 DUP (?)
  118. STACK    DW      0
  119. ;
  120. PAGE
  121. ;
  122. ;        THIS CODE USED ONLY DURING SETUP, NO NEED TO KEEP IT
  123. ;
  124. ;---module dosvtst.asm
  125. ;
  126. ;        verifies that DOS version is 2.0 or above, else aborts
  127. ;
  128. dosvtst:
  129.         mov      ah,30h          ;version check
  130.         int      21h
  131.         xchg     ah,al
  132.         cmp      ax,0200h        ;2.0 and above
  133.         jae      vrsnok
  134.         mov      dx,offset wvm
  135.         mov      ah,9
  136.         int      21h
  137.         int      20h
  138. wvm      db      'DOS 2.0 or above is required',13,10,'$'
  139. vrsnok:  ret                     ;version is appropriate
  140. ;
  141. ;---end module dosvtst.asm
  142. ;
  143. PAGE
  144. ;
  145. ;---module getpath.asm
  146. ;
  147. ;        converts first string of command tail into ASCIIZ
  148. ;                pathname for DOS use.
  149. ;        destroys registers AX, CX, DX, SI, and DI
  150. ;        modifies flags
  151. ;
  152. GETPATH:
  153.         CLD
  154.         MOV      SI,80H          ;command tail in PSP
  155.         LODSB                    ;get char count
  156.         AND      AL,127          ;test for no chars at all
  157.         JZ       PATH5           ;none, don't scan
  158.         CBW
  159.         MOV      CX,AX           ;else put into CX
  160. PATH0:   MOV     DX,SI           ;save start offset
  161.         MOV      DI,SI
  162.         LODSB                    ;ignore leading blank
  163.         CMP      AL,' '
  164.         JA       PATH2           ;non-blank, go look for end
  165.         LOOP     PATH0           ;leading blank, look more
  166.         JMP      SHORT PATH4     ;nothing found
  167. ;
  168. PATH1:   MOV     DI,SI           ;save for case fix
  169.         LODSB                    ;look for terminator
  170.         CMP      AL,' '
  171.         JBE      PATH4           ;found it
  172. PATH2:   CMP     AL,'a'          ;not seen, check case
  173.         JB       PATH3
  174.         CMP      AL,'z'
  175.         JA       PATH3
  176.         AND      AL,5FH          ;lowercase, make upper
  177. ;
  178. ; Next 2 lines added by L.P., 10/29/85
  179. ; Store byte in all cases to increment DI properly
  180. PATH3:   STOSB
  181.          LOOP    PATH1
  182. ;
  183. ;Next 2 lines removed by L.P., 10/29/85
  184. ;       STOSB
  185. ; PATH3:   LOOP    PATH1
  186. ;
  187. ;  Next line removed by L.P., 10/29/85
  188. ;       INC      DI              ;to CR's location at EOS
  189. ;
  190. PATH4:   XOR     AL,AL           ;force a zero
  191.         MOV      [DI],AL
  192.         MOV      AX,DI
  193.         SUB      AX,DX
  194. PATH5:   RET                     ;path converted
  195. ;
  196. ;        Z-flag is set if no pathname was present,
  197. ;        else:   AX = number of characters in pathname
  198. ;                CX = 0
  199. ;                DX points to pathname's first character
  200. ;                SI points to character past terminator (or NULL if no more)
  201. ;                DI points to terminating NULL of pathname
  202. ;
  203. ;---end module getpath.asm
  204. PAGE
  205. ;
  206. GETCOM:  MOV     SI,02CH                 ;search Environment for COMSPEC
  207.         MOV      SI,[SI]
  208.         MOV      DS,SI
  209.         MOV      PARMS,SI                ;use parent's environment
  210.         MOV      SI,0
  211.         LODSB
  212. NXT:     MOV     BX,OFFSET ENVSTR
  213.         CMP      AL,ES:[BX]
  214.         JNZ      SKIP                    ;no initial match
  215.         MOV      CX,7
  216. CHK:     LODSB
  217.         INC      BX
  218.         CMP      AL,ES:[BX]
  219.         JNZ      SKIP                    ;failed after start
  220.         LOOP     CHK
  221.         RET                              ;if we get here it's found
  222. ;
  223. ENVSTR   DB      'COMSPEC='
  224. ;
  225. SKIP:    LODSB                           ;find EOS
  226.         OR       AL,AL
  227.         JNZ      SKIP
  228.         LODSB                            ;test for end of Environment
  229.         OR       AL,AL
  230.         JNZ      NXT                     ;more to check
  231.         MOV      DX,OFFSET NOENV         ;hit the end!
  232.         JMP      FINI
  233. ;
  234. NOPATH   DB      13,10,'Pathname is required',13,10,36
  235. NOENV    DB      13,10,'No COMSPEC= found',13,10,36
  236. ;
  237. PAGE
  238. ;
  239. REDIR:   MOV     CX,0
  240.         MOV      AH,3CH                  ;create file
  241.         INT      21H
  242.         JC       DSKERR
  243.         MOV      BX,AX                   ;handle
  244.         MOV      SI,18H                  ;handle table offset in PSP
  245.         MOV      AL,[BX][SI]             ;DCB index for new file
  246.         MOV      [BX][SI],BYTE PTR 255   ;mark its handle as closed
  247.         MOV      AH,[SI][4]              ;DCB index for PRN handle
  248.         MOV      [SI][4],AL              ;set new file in as PRN
  249.         RET                              ;if no error (indices in AX)
  250. ;
  251. DSKERR:
  252.         cmp      ax,19
  253.         jl       valerr
  254.         mov      dx,offset uem
  255.         jmp      short abrt
  256. valerr:  add     ax,ax
  257.         mov      bx,offset emt
  258.         add      bx,ax
  259.         mov      dx,[bx]
  260. abrt:    mov     ah,9
  261.         int      21h
  262.         mov      dx,offset emg2
  263.         mov      ah,9
  264.         int      21h
  265. done:    int     20h
  266. ;
  267. emg2     db      '.',13,10
  268.         db       'ABORTED.',7,13,10,'$'
  269. ;
  270. emt      dw      uem,em1,em2,em3,em4,em5,em6,em7
  271.         dw       em8,em9,em10,em11,em12,em13,uem
  272.         dw       em15,em16,em17,em18
  273. ;
  274. uem      db      'Unknown error code$'
  275. em1      db      'Bad call$'
  276. em2      db      'No file found$'
  277. em3      db      'Path not found$'
  278. em4      db      'Out of handles$'
  279. em5      db      'Access denied$'
  280. em6      db      'Handle bad$'
  281. em7      db      'Memory fouled$'
  282. em8      db      'No more RAM$'
  283. em9      db      'Bad adr$'
  284. em10     db      'Bad ENV$'
  285. em11     db      'Bad format$'
  286. em12     db      'Bad access code$'
  287. em13     db      'Bad data$'
  288. em15     db      'Drive not valid$'
  289. em16     db      'Dir error$'
  290. em17     db      'Wrong device$'
  291. em18     db      'Out of files$'
  292. ;
  293. CODE     ENDS
  294.         END      START
  295.